package model

import (
	"context"
	"gorm.io/gorm"
)

type (
	UserRole interface {
		Insert(ctx context.Context, userId, roleId int) error
		BatchInsert(ctx context.Context, userId int, roleIds []int) error
		FindByUserId(ctx context.Context, userId int) (*AuthxUserRole, error)
		FindByUserIdAndRole(ctx context.Context, userId, roleId int) ([]*AuthxUserRole, error)
		Delete(ctx context.Context, userId, roleId int) error
		DeleteByUserId(ctx context.Context, userId int) error
		Update(ctx context.Context, userId, roleId int) error
	}

	defaultUserRole struct {
		db *gorm.DB
	}
)

func NewUserRole(db *gorm.DB) UserRole {
	return &defaultUserRole{
		db: db,
	}
}

func (d *defaultUserRole) model() *gorm.DB {
	return d.db.Model(&AuthxUserRole{})
}

func (d *defaultUserRole) Insert(ctx context.Context, userId, roleId int) error {
	return d.db.Create(&AuthxUserRole{
		UserId: userId,
		RoleId: roleId,
	}).Error
}

func (d *defaultUserRole) BatchInsert(ctx context.Context, userId int, roleIds []int) error {
	var records []*AuthxUserRole
	for _, roleId := range roleIds {
		records = append(records, &AuthxUserRole{
			UserId: userId,
			RoleId: roleId,
		})
	}
	return d.db.Create(&records).Error
}

func (d *defaultUserRole) FindByUserId(ctx context.Context, userId int) (*AuthxUserRole, error) {
	var result AuthxUserRole

	err := d.model().Where("user_id = ?", userId).First(&result).Error
	switch err {
	case nil:
		return &result, nil
	case gorm.ErrRecordNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}
func (d *defaultUserRole) FindByUserIdAndRole(ctx context.Context, userId, roleId int) ([]*AuthxUserRole, error) {
	var result []*AuthxUserRole
	if err := d.model().Where("user_id = ? and role_id = ?", userId, roleId).Find(&result).Error; err != nil {
		return nil, err
	}
	return result, nil
}

func (d *defaultUserRole) Delete(ctx context.Context, userId, roleId int) error {
	return d.model().
		Where("user_id = ? AND role_id = ?", userId, roleId).
		Delete(&AuthxUserRole{}).Error
}

func (d *defaultUserRole) DeleteByUserId(ctx context.Context, userId int) error {
	return d.model().
		Where("user_id = ?", userId).
		Delete(&AuthxUserRole{}).Error
}

func (d *defaultUserRole) Update(ctx context.Context, userId, roleId int) error {
	return d.model().Where("user_id = ?", userId).Update("role_Id = ?", roleId).Error

}
